home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue54 / Persist / tiUtils.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  2000-01-21  |  6.7 KB  |  220 lines

  1. {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  2.   (c) TechInsite Pty. Ltd.
  3.   PO Box 429, Abbotsford, Melbourne. 3067 Australia
  4.   Phone: +61 3 9419 6456
  5.   Fax:   +61 3 9419 1682
  6.   Web:   www.techinsite.com.au
  7.   EMail: peter_hinrichsen@techinsite.com.au
  8.  
  9.   Created: Jan 2000
  10.  
  11.   Notes: Utility functions
  12.  
  13. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
  14. unit TIUtils ;
  15.  
  16. interface
  17. uses
  18.  
  19.   Classes
  20.   ,TypInfo
  21.   ;
  22.  
  23. const
  24.  
  25.   // Type kinds for use with tiGetPropertyNames
  26.   // All string type properties
  27.   ctkString = [ tkChar, tkString, tkWChar, tkLString, tkWString ] ;
  28.   // Integer type properties
  29.   ctkInt    = [ tkInteger, tkInt64 ] ;
  30.   // Float type properties
  31.   ctkFloat  = [ tkFloat ] ;
  32.   // All simple types (string, int, float)
  33.   ctkSimple = ctkString + ctkInt + ctkFloat ;
  34.  
  35. type
  36.   // Simple TypeKinds, as summary of the TTypeKinds available in TypInfo
  37.   TtiTypeKind =  ( tiTKInteger, tiTKFloat , tiTKString ) ;
  38.  
  39.   // These are all the possibilities
  40.   // tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat,
  41.   // tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString,
  42.   // tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray);
  43.  
  44.   // Count the number of fields in a string as delimited by psToken
  45.   function  tiNumToken(         const pStrValue, pStrToken : string ) : integer ;
  46.   // Extract the pIntNum(th) field from as string as delimited by psToken
  47.   function  tiToken(            const pStrValue, pStrToken : string; const pIntNum : integer ) : string ;
  48.   // Swap the pStrDel characters in a string with pStrIns
  49.   function  tiStrTran(          pStrValue, pStrDel, pStrIns : string ) : string ;
  50.  
  51.   // Convert a propert from Delphis TTypeKind to TtiSimpleTypeKind
  52.   // EG: Change tkInteger, tkInt64 and tkEnumeration to tkInteger
  53.   function tiGetSimplePropType( pPersistent : TPersistent ; psPropName : string ) : TtiTypeKind ;
  54.   // Read a TPersistent's published properties into a TStringList
  55.   procedure tiGetPropertyNames( pPersistent : TObject ;
  56.                                 pSL : TStringList ;
  57.                                 pPropFilter : TTypeKinds = ctkSimple ) ;
  58.  
  59. implementation
  60. uses
  61.   SysUtils
  62.   ;
  63.  
  64. // Seaches <sStr> and replaces <sDel> with <sIns>
  65. // Case sensitive.
  66. //------------------------------------------------------------------------------
  67. function tiStrTran( pStrValue, pStrDel, pStrIns : string ) : string ;
  68. var i : integer ;
  69.     sToChange : string ;
  70. begin
  71.   result := '' ;
  72.   sToChange := pStrValue ;
  73.   i := pos( pStrDel, sToChange ) ;
  74.   while i <> 0 do begin
  75.     result := result + copy( sToChange, 1, i-1 ) + pStrIns ;
  76.     delete( sToChange, 1, i+length( pStrDel )-1) ;
  77.     i := pos( pStrDel, sToChange ) ;
  78.   end ;
  79.   result := result + sToChange ;
  80. end ;
  81.  
  82. //------------------------------------------------------------------------------
  83. function tiNumToken( const pStrValue, pStrToken : string ) : integer ;
  84. var
  85.   i, iCount : integer ;
  86.   lsValue : string ;
  87. begin
  88.   iCount := 0 ;
  89.   lsValue := pStrValue ;
  90.   i := pos( pStrToken, lsValue ) ;
  91.   while i <> 0 do begin
  92.     delete( lsValue, i, length( pStrToken )) ;
  93.     inc( iCount ) ;
  94.     i := pos( pStrToken, lsValue ) ;
  95.   end ;
  96.   result := iCount + 1 ;
  97. end ;
  98.  
  99. //------------------------------------------------------------------------------
  100. function tiToken( const pStrValue, pStrToken : string; const pIntNum : integer ) : string ;
  101. var
  102.   i, iCount, iNumToken : integer ;
  103.   lsValue : string ;
  104. begin
  105.  
  106.   result := '' ;
  107.  
  108.   iNumToken := tiNumToken( pStrValue, pStrToken ) ;
  109.   if pIntNum = 1 then begin
  110.     if pos( pStrToken, pStrValue ) = 0 then result := pStrValue
  111.     else result := copy( pStrValue, 1, pos( pStrToken, pStrValue )-1) ;
  112.     end
  113.   else if (iNumToken < pIntNum-1) or (pIntNum<1) then begin
  114.     result := '' ;
  115.     end
  116.   else begin
  117.  
  118.     { Remove leading blocks }
  119.     iCount := 1 ;
  120.     lsValue := pStrValue ;
  121.     i := pos( pStrToken, lsValue ) ;
  122.     while (i<>0) and (iCount<pIntNum) do begin
  123.       delete( lsValue, 1, i + length( pStrToken ) - 1 ) ;
  124.       inc( iCount ) ;
  125.       i := pos( pStrToken, lsValue ) ;
  126.     end ;
  127.  
  128.     if (i=0) and (iCount=pIntNum) then result := lsValue
  129.     else if (i=0) and (iCount<>pIntNum) then result := ''
  130.     else result := copy( lsValue, 1, i-1) ;
  131.  
  132.   end ;
  133. end ;
  134.  
  135. //------------------------------------------------------------------------------
  136. function tiMixedCase( pStrValue : string ) : string ;
  137. var iToken : integer ;
  138.     i : integer ;
  139.     sBuffer : string ;
  140. begin
  141.   iToken := tiNumToken( pStrValue, ' ' ) ;
  142.   result := '' ;
  143.   pStrValue := lowerCase( pStrValue ) ;
  144.   for i := 1 to iToken do begin
  145.     sBuffer := tiToken( pStrValue, ' ', i ) ;
  146.     if result <> '' then result := result + ' ' ;
  147.     result  := result +
  148.                upperCase( copy( sBuffer, 1, 1 )) +
  149.                copy( sBuffer, 2, length( sBuffer ) - 1 ) ;
  150.   end ;
  151. end ;
  152.  
  153. procedure tiGetPropertyNames( pPersistent : TObject ; pSL : TStringList ;
  154.                               pPropFilter : TTypeKinds = ctkSimple ) ;
  155. var
  156.   lCount : integer ;
  157.   lSize  : integer ;
  158.   lList  : PPropList ;
  159.   i : integer ;
  160.   lPropFilter : TTypeKinds ;
  161. begin
  162.   Assert( pPersistent <> nil, 'pPersistent not assigned.' ) ;
  163.   Assert( pSL <> nil, 'pSL not assigned.' ) ;
  164.   lPropFilter := pPropFilter ;
  165.  
  166.   pSL.Clear ;
  167.  
  168.   lCount := GetPropList(pPersistent.ClassInfo, lPropFilter, nil);
  169.   lSize := lCount * SizeOf(Pointer);
  170.   GetMem(lList, lSize);
  171.   try
  172.     GetPropList(pPersistent.ClassInfo, lPropFilter, lList);
  173.     for i := 0 to lcount - 1 do
  174.       psl.add( lList[i].Name ) ;
  175.   finally
  176.     FreeMem( lList, lSize ) ;
  177.   end ;
  178.  
  179. end ;
  180.  
  181. //  TTypeKind = ( tkUnknown, tkInteger, tkChar, tkEnumeration, tkFloat,
  182. //                tkString, tkSet, tkClass, tkMethod, tkWChar, tkLString, tkWString,
  183. //                tkVariant, tkArray, tkRecord, tkInterface, tkInt64, tkDynArray);
  184. //------------------------------------------------------------------------------
  185. function tiGetSimplePropType( pPersistent : TPersistent ; psPropName : string ) : TtiTypeKind ;
  186. var
  187.   lPropType : TTypeKind ;
  188. begin
  189.  
  190.   try
  191.     lPropType := PropType( pPersistent, psPropName ) ;
  192.   except
  193.     on e:exception do
  194.       raise exception.create( 'Error in tiGetSimpleTypeKind ' +
  195.                               'Message: ' + e.message ) ;
  196.   end ;
  197.  
  198.   case lPropType of
  199.   tkInteger,
  200.   tkInt64,
  201.   tkEnumeration : result := tiTKInteger ;
  202.  
  203.   tkFloat       : result := tiTKFloat ;
  204.  
  205.   tkString,
  206.   tkChar,
  207.   tkWChar,
  208.   tkLString,
  209.   tkWString     : result := tiTKString ;
  210.  
  211.   else
  212.     raise exception.create( 'Invalid property type passed to ' +
  213.                             'tiGetSimpleTypeKind' ) ;
  214.   end ;
  215.  
  216. end;
  217.  
  218. end.
  219.  
  220.